﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;


[AddComponentMenu("Behavior/MoveTo")]
public class BhvMoveTo : MonoBehaviour
{

    public GameObject targetObject;
    private Vector3 targetPos;
    private bool _isRunning = false;

    public bool activeAtStart = false;
    public float speed = 1;
    public float speedMax = 1;
    public float acceleration = 0;
    public bool isRotateToTarget = true;
    private float closeLimitRange = 0.1f;
    
    [Tooltip("除非手动停止,是否一直跟随移动，无论是否达到目标")]
    public bool followForever = false;

    public UnityEvent onFinishEvents;

    // Start is called before the first frame update
    void Start()
    {
        if (activeAtStart)
        {
            this._isRunning = true;
        }
    }

    public void setSpeed(float speed = 200, float speedMax = 500, float accel = 500)
    {
        this.speed = speed;
        this.speedMax = speedMax;
        this.acceleration = accel;
    }

    public void MoveToObject(GameObject gameObject)
    {
        this.targetObject = gameObject;
        this._isRunning = true;
    }

    public void MoveTo(Vector3 position)
    {
        this.targetObject = null;
        this.targetPos = position;
        this._isRunning = true;
    }

    public void Stop()
    {
        this._isRunning = false;
    }

    private void UpdateTarget()
    {
        if (!this.targetObject) return;
        this.targetPos = this.targetObject.transform.position;
    }

    // Update is called once per frame
    void Update()
    {
        if ((!this.enabled) || (!this._isRunning))
        {
            return;
        }

        var dt = Time.deltaTime;
        UpdateTarget();//检查有没有绑定目标
        var limitMin = closeLimitRange;
        var cur = transform.position;
        var tar = targetPos;

        //加速度影响
        this.speed += this.acceleration * dt;
        if (this.speed >= this.speedMax) this.speed = this.speedMax;
        if (this.speed < 0) this.speed = 0;

        var movingDist = this.speed * dt;//移动距离
        var distToTarget = (cur - tar).magnitude;//目标距离

        if (distToTarget < limitMin)
        {
            if (!this.followForever)
            {
                _isRunning = false;
            }
            OnComplete();
        }

        if ((this.speed == 0) || (dt == 0))
        {
            return;
        }


        Vector3 newPos = new Vector3();
        if (movingDist < distToTarget)
        {
            var t = movingDist / distToTarget;
            newPos = Vector3.Lerp(cur, tar, t);
        }
        else
        {
            newPos = tar;
        }

        transform.position = newPos;

        if (isRotateToTarget)
        {
            transform.LookAt(tar);
        }
    }

    private void OnComplete()
    {
        onFinishEvents?.Invoke();
    }
}
